<?php

class Report extends AppModel
{

	public $name = 'Report';

	public $displayField = 'name';

	protected $types = array(
	   'SIMPLE',
	   'CONSOLIDATED',
	);

	public $validate = array(
        'name' => array(
            'create_first' => array(
                'on' => 'create',
                'required' => true,
                'allowEmpty' => false,
                'message' => 'required',
            ),
            'update_first' => array(
                'on' => 'update',
                'required' => false,
                'allowEmpty' => false,
                'message' => 'required',
            ),
        ),
	);

	public $hasAndBelongsToMany = array(
        'Tests' => array('className' => 'Test', 'joinTable' => 'tests_reports'),
	);
	public $hasMany = array(
        'Reportings' => array('className' => 'Reporting'),
	);

	function allowDelete($fields = null)
	{
        return false;
	}

	function allowUpdate($fields = null)
	{
        return true;
	}

	function generateList($conds = array())
	{
	    /*
	    if (Auth::o()->is('client_admin')) {
            $Client =& $this->getModel('Client');
            $auth_data = Auth::o()->data();
            $conds[]['`Clients`.`id`'] = $auth_data['client_id'];
            $Client->rel('Tests.Reports');
            $rows = $Client->findAll($conds, array('Tests.Reports.'.$this->primaryKey, 'Tests.Reports.'.$this->name));
            return array();
	    }*/
	    $this->rel();
        return parent::generateList($conds, $this->primaryKey, null, "{n}.{$this->name}.{$this->primaryKey}", "{n}.{$this->name}.{$this->displayField}");
	}

	function generateReport($params, &$reporting_id)
	{
		if (empty($params['Candidate']) || empty($params['Client']) || empty($params['Testing']) || empty($params['Report']) || empty($params['Test']) || !array_key_exists('Norm', $params)) {
			throw new ArgException('', 3001);
		}

		$Reporting =& $this->getModel('Reporting'); /* @var $Reporting Reporting */

		$candidate = $params['Candidate'];
		$client    = $params['Client'];
		$report    = $params['Report'];
		$norm      = $params['Norm'];
		$test      = $params['Test'];
		$testing   = $params['Testing'];

		$generate_result = null;
	    $this->generatePDF($params, $generate_result);

	    $data = array($Reporting->name => array (
    	    'report_id'    => $report['id'],
    	    'testing_id'   => !empty($testing['id']) ? $testing['id'] : null,
    	    'norm_id'      => $params['Test']['type'] == 'TEST' ? $norm['id'] : null,
    	    'date'         => Date::Unix2SQL(time()),
    	    'blob_id'      => $generate_result['blob_id'],
    	    'client_id'    => !empty($client['id']) ? $client['id'] : null,
	    ));
	    if (! $Reporting->save($Reporting->create($data), false)) {
	        throw new Exception('', 3002);
	    }
	    $reporting_id = $Reporting->getInsertID();
	    $reporting = $data;
	    $reporting['id'] = $reporting_id;

        $client_admins = $this->getModel('ClientAdmin')->getRecepientsReportEmails($client['id']);
        if (count($client_admins)) {
            $params = array();
    		$params['blob'] = array('id' => $generate_result['blob_id']);
    		$params['candidate'] = $candidate;
    		$params['client'] = $client;
    		$params['report'] = $report;
    		$params['reporting'] = $reporting;
    		$params['norm'] = $norm;
    		$params['test'] = $test;
    		$params['testing'] = $testing;
    		$params['delayed'] = true;
        	foreach ($client_admins as $client_admin) {
        		$params['client_admin'] = $client_admin['ClientAdmin'];
                try {
                    $this->getModel('SendMail')->sendReport($params);
                } catch (Exception $e) {}
        	}
    	}
	}

	protected function generatePDF($params, &$result)
	{
		$test      = $params['Test'];
		$report    = $params['Report'];
		$testing   = $params['Testing'];
		$norm      = $params['Norm'];
		$candidate = $params['Candidate'];

        /**  Generating PDF *******/
 		$reportClassFileName = $report['report_file_name'];
		$reportClassName = $report['report_class_name'];

		if (! vendor('report/'.$reportClassFileName)) {
			throw new Exception('Report class file not found: '.$reportClassFileName, 3004);
		}
		if (! class_exists($reportClassName)) {
			throw new Exception('Report class not exists: '.$reportClassName, 3005);
		}

		$instrumentClassFileName = $test['tool_file_name'];
		$instrumentClassName = $test['tool_class_name'];

		if (! vendor('instrument/'.$instrumentClassFileName)) {
			throw new Exception('Tool class file not found: '.$instrumentClassFileName, 3006);
		}
		if (! class_exists($instrumentClassName)) {
			throw new Exception('Tool class not exists: '.$instrumentClassName, 3007);
		}

		switch($test['type']) {

		case 'TEST':
			$t = new $instrumentClassName($testing['result'], $norm['id']);
			break;

		case 'QUEST':
			$t = new $instrumentClassName($testing['result']);
			break;

		default:
			throw new Exception('Unknown tool type: '.$test['type'], 3008);
			break;
		}
		$d = $t->getReportData();
		$d->person = $candidate['name_latin'].' '.$candidate['surname_latin'];
		$d->tool = $test['name'];
		$d->tool_full_desc = $test['full_name'];
		$d->testing_date = date('Y-m-d', strtotime($testing['date']));
		$d->repord_date = date('Y-m-d');
		$d->copyright = 'Human Resources Technologies. Version '.X_VERSION;

		$r = new $reportClassName($d);
		$PDF = $r->draw();
        /** ^^^^^^^^ END Generating PDF ^^^^^^^^^ *******/

		$Blob =& $this->getModel('Blob'); /* @var $Blob Blob */
		if (! $Blob->save($Blob->create(array($Blob->name => array('data' => $PDF))))) {
			throw new DBException('', 3010);
		}
		$result['blob_id'] = $Blob->getInsertID();
	}

	function getTypes()
	{
	    return $this->types;
	}

	function getTypesList()
	{
	    $result = array();
	    foreach ($this->types as $type) {
	        $result[$type] = __d('reports', 'type_'.$type, true);
	    }
	    return $result;
	}

	function generateConsReport($params, &$reporting_id, &$num_bad_candidates)
	{
		if (empty($params['Testings']) || empty($params['Client']) || empty($params['Report']) || empty($params['Test']) || empty($params['Norm'])) {
			throw new ArgException('', 3011);
		}

		$Reporting =& $this->getModel('Reporting'); /* @var $Reporting Reporting */

		$client    = $params['Client'];
		$report    = $params['Report'];
		$norm      = $params['Norm'];
		$test      = $params['Test'];

		$num_bad_candidates = 0;
		$candidates = null;
		if ($report['type'] !== 'CONSOLIDATED') {
			throw new ArgException('', 3011);
		}
		$candidates = array();

		foreach ($params['Testings'] as $row) {
			vendor('instrument/'.$row['Test']['tool_file_name']);
			try
			{
				$tool = new $row['Test']['tool_class_name']($row['Testing']['result'], $norm['id']);
				list($tScore, $pcScore) = $tool->getScores();
				$candidates[] = array(
	                'name' => $row['Candidate']['name'].' '.$row['Candidate']['surname'],
	                'tscore' => $tScore,
	                'percentile' => $pcScore,
	                'testing_date' => $row['Testing']['date'],
	            );
			}
			catch (Exception $e)
			{
			    if (in_array($e->getCode(), array(2010, 2011, 2012, 2013, 2020, 2030))) {
                    $num_bad_candidates++;
			    } else {
			        throw $e;
			    }
			}
		}
		if ((count($params['Testings']) - $num_bad_candidates) <= 1) {
            throw new Exception("Must be at least two candidates", 1029);
		}

	    if (empty($candidates)) {
	        throw new ArgException("Empty of candidates list", 1013);
	    }
	    $params["Testings"] = $candidates;

		$generate_result = null;
	    $this->generateConsPDF($params, $generate_result);

	    $data = array($Reporting->name => array (
    	    'report_id'    => $report['id'],
    	    'testing_id'   => null,
    	    'norm_id'      => $params['Test']['type'] == 'TEST' ? $norm['id'] : null,
    	    'date'         => Date::Unix2SQL(time()),
    	    'blob_id'      => $generate_result['blob_id'],
    	    'client_id'    => !empty($client['id']) ? $client['id'] : null,
	    ));
	    if (! $Reporting->save($Reporting->create($data), false)) {
	        throw new Exception('', 3012);
	    }
	    $reporting_id = $Reporting->getInsertID();
	    $reporting = $data;
	    $reporting['id'] = $reporting_id;

        $client_admins = $this->getModel('ClientAdmin')->getRecepientsReportEmails($client['id']);
        if (count($client_admins)) {
            $params = array();
    		$params['blob'] = array('id' => $generate_result['blob_id']);
    		$params['candidates'] = $candidates;
    		$params['client'] = $client;
    		$params['report'] = $report;
    		$params['reporting'] = $reporting;
    		$params['norm'] = $norm;
    		$params['test'] = $test;
    		$params['delayed'] = true;
        	foreach ($client_admins as $client_admin) {
        		$params['client_admin'] = $client_admin['ClientAdmin'];
                try {
                    $this->getModel('SendMail')->sendReport($params);
                } catch (Exception $e) {}
        	}
    	}
	}

	protected function generateConsPDF($params, &$result)
	{
		$report     = $params['Report'];
		$norm       = $params['Norm'];
		$candidates = $params['Testings'];
		$test = $params['Test'];

        /**  Generating PDF *******/
 		$reportClassFileName = $report['report_file_name'];
		$reportClassName = $report['report_class_name'];

		if (! vendor('report/'.$reportClassFileName)) {
			throw new Exception('Report class file not found: '.$reportClassFileName, 3004);
		}
		if (! class_exists($reportClassName)) {
			throw new Exception('Report class not exists: '.$reportClassName, 3005);
		}

		vendor('report/cons_data');
		$d = new ConsData();
		$d->normgroup = $norm['name'];
		$d->tool = $test['name'];
		$d->tool_full_desc = '';
		$d->candidates = $candidates;
		$d->candgroup = null;
		$d->repord_date = date('Y-m-d');
		$d->copyright = 'Human Resources Technologies. Version '.X_VERSION;

		$r = new $reportClassName($d);
		$PDF = $r->draw();
        /** ^^^^^^^^ END Generating PDF ^^^^^^^^^ *******/

		$Blob =& $this->getModel('Blob'); /* @var $Blob Blob */
		if (! $Blob->save($Blob->create(array($Blob->name => array('data' => $PDF))))) {
			throw new DBException('', 3010);
		}
		$result['blob_id'] = $Blob->getInsertID();
	}
}

?>